#ifndef NETWORK_SERVER_H
#define NETWORK_SERVER_H

#include <string.h> // memset
#include <stdlib.h> // exit
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <queue>
#include <set>

#include "../utils/data_types.h"
#include "Network.h"
#include "NetworkMessage.h"

class NetworkServer : public Network
{
    public:
        
        // :THREADED:
        ~NetworkServer();
        
        void Connect(int port);
        
        bool Broadcast(NetworkMessage* msg);
        
        Event<int>& OnNewConnection();
        // :TODO: @author: tfischer
        // cambiar nombre por OnConnectionLost();
        Event<int>& OnConnectionClosed();

    protected:
        
        // @Override Network :THREADED:
        void PrepareSet();
        
        // @Override Network :THREADED:
        void HandleActiveSockets();
        
        // @Override Network :THREADED:
        void LostConnectionHandler(int target_sock_fd);
        
    private:
        
        // :THREADED:
        std::set<int> client_sockets;
        Mutex client_sockets_mutex;
        
        Event<int> _new_connection_event;
        Event<int> _connection_closed_event;
        
        // :THREADED:
        void HandleNewClient();
};

#endif
